#include <Arduino.h>
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/task.h" 
#include "freertos/timers.h"
#include "struct_def.h"
 
#include "lvgl.h"
#include "lv_driver.h"
#include "ui.h"
#include "PCA9554.h"

extern PCA9554 io; 

   #include "app/weather.h"
#include "HTTPClient.h"
#include "SD.h"
#include "SPI.h"
File root;
#include "SparkFunCCS811.h"
CCS811 mySensor(0x5A);

extern lv_chart_series_t * ser1;
extern lv_obj_t *chart_co2;
static void lvgl_loop(void *para);
static void time_task(void *para);

#define TASK_QUEUE_MSG_LEN  20

EventGroupHandle_t g_sync_event_group = NULL;
QueueHandle_t g_event_queue_handle = NULL;

void WiFiEvent(WiFiEvent_t event);
void setup(void) {
    
      Serial.begin(115200); 
      Serial.printf("free heap:%d\n" ,esp_get_free_heap_size() );
      g_event_queue_handle = xQueueCreate(TASK_QUEUE_MSG_LEN,sizeof(task_event_data_t));
      g_sync_event_group = xEventGroupCreate();
      WiFi.onEvent(WiFiEvent);
      lv_init();
      lv_driver_init();
      ui_create();
      Serial.printf("free heap:%d\n" ,esp_get_free_heap_size() );
      io.digitalWrite0(3,1);
      digitalWrite(15,1);
      if (!SD.begin(14)) 
      {
          Serial.println("initialization failed!");        
      }
      else
      {
          Serial.println("initialization done.");
      }

  // xTaskCreate(time_task, "time", 2048, NULL, 20, NULL);
 
 

 
 
}
void wifi_handle(void *data);
void weather_handle(void *data);
void time_handle(void *data);
void loop() 
{
     task_event_data_t event_data;
     while(1)
     {
       Serial.printf("[while qeue_cnt]---------------:%d\n",uxQueueMessagesWaiting( g_event_queue_handle )); ;
        if(xQueueReceive(g_event_queue_handle,&event_data,portMAX_DELAY) == pdPASS)
        {
            switch(event_data.type)
            {
              case MSG_TIME:time_handle(&event_data.time);break;
              case MSG_MOTION:break;
              case MSG_WIFI:wifi_handle(&event_data.wifi);break;
              case MSG_VOLUME:break;
              case MSG_POWER:break;
              case MSG_WEATHER:weather_handle(&event_data.wewather);break;
              default:break;
            }
        }
     }
}

#include "NTPClient.h" 
#include "RTClib.h"
bool state_time_sync = false;
extern PCF8563 rtc;
extern lv_obj_t *scr_tft ;
extern lv_obj_t *scr_eink ;
extern lv_obj_t *label_menu;
 // Set offset time in seconds to adjust for your timezone, for example:
  // GMT +1 = 3600
  // GMT +8 = 28800
  // GMT -1 = -3600
  // GMT 0 = 0
extern NTPClient timeClient;//+8区，60*60*8
//time handle
static void time_task(void *para)
{
  DateTime now;
  char buf[100];
  while(1)
  {
    // now = rtc.now();    
    // strncpy(buf,"YYYY.MM.DD\nhh:mm:ss",100);
    // Serial.println(now.format(buf));
    // lv_label_set_text(label_menu,now.format(buf));
    // lv_obj_align(label_menu,scr_tft,LV_ALIGN_CENTER,0,0);
    delay(1000*1);
     
  }
}
void time_handle(void *data)
{
   
  time_struct_t *p = (time_struct_t *)data;
  // task_event_data_t event_data;
  
  switch(p->event)
  {
    case TIME_SYNC:
        {
            // String formattedDate;
            // String dayStamp;
            // String timeStamp;
            // timeClient.begin();

            // timeClient.forceUpdate();
            // // The formattedDate comes with the following format:
            // // 2018-05-28T16:00:13Z
            // // We need to extract date and time
            // formattedDate = timeClient.getFormattedDate();
            
            // Serial.println(formattedDate);
            // int splitT = formattedDate.indexOf("T");
            // dayStamp = formattedDate.substring(0, splitT);
            // timeStamp = formattedDate.substring(splitT+1, formattedDate.length()-1);
            // rtc.adjust(DateTime(dayStamp.c_str(), timeStamp.c_str()));    

            // state_time_sync = true;        
            break;


        }
        
    case TIME_ALARM:break;
    case TIME_UPDATE:break;
    default:break;
  }

}






//wifi handle
#include "app/app.h"
static TimerHandle_t timerhandle_wifi = NULL;
static void vTimerCallback(xTimerHandle pxTimer)
{
  
  task_event_data_t event_data;
  
  event_data.type = MSG_WIFI;
  if(WiFi.status() != WL_CONNECTED)
  {
    event_data.wifi.event = WIFI_CONFIG_CONNECT_FAIL;
  }
  else
  {
    // event_data.wifi.event = WIFI_CONFIG_CONNECT_SUCCESS;
  }
  
  xQueueSend(g_event_queue_handle,&event_data, portMAX_DELAY);

}

void WiFiEvent(WiFiEvent_t event)
{
    // Serial.printf("[WiFi-event] event: %d\n", event);

    switch(event)
    {

        case SYSTEM_EVENT_STA_GOT_IP:
            Serial.println("WiFi connected");
            Serial.println("IP address: ");
            Serial.println(WiFi.localIP());
            task_event_data_t event_data;
            event_data.type = MSG_WIFI;
            event_data.wifi.event = WIFI_CONFIG_CONNECT_SUCCESS;
            xQueueSend(g_event_queue_handle, &event_data, portMAX_DELAY);
            break;
        case SYSTEM_EVENT_STA_DISCONNECTED:
            Serial.println("WiFi lost connection");
            break;
        case SYSTEM_EVENT_STA_CONNECTED:
            Serial.println("Connected to access point");
            break;
        default:break;
    
    }
}
void wifi_handle(void *data)
{
    int16_t len;
    task_event_data_t event_data;
    wifi_struct_t *p = (wifi_struct_t *)data;
    wifi_auth_t *auth = (wifi_auth_t *)p->ctx;
    wl_status_t ret ;
    // memcpy(auth->ssid,WIFI_SSID,sizeof(WIFI_SSID));
    // memcpy(auth->password,WIFI_PASSWORD,sizeof(WIFI_PASSWORD));
    // auth->ssid=WIFI_SSID;
    // auth->password = WIFI_PASSWORD;
    switch(p->event)
    {
      case WIFI_CONFIG_SCAN:
          Serial.println("WIFI Scan Start ...");
          WiFi.mode(WIFI_STA);
          WiFi.disconnect();
          len = WiFi.scanNetworks();
          Serial.printf("WIFI Scan Done ... [%d]\n",len);
          for (int i = 0; i < len; ++i)
          {
            // Print SSID and RSSI for each network found
            Serial.print(i + 1);
            Serial.print(": ");
            Serial.print(WiFi.SSID(i));
            Serial.print(" (");
            Serial.print(WiFi.RSSI(i));
            Serial.print(")");
            Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?" ":"*");
            // delay(10);
          }
          WiFi.scanDelete();
          WiFi.disconnect(true);
          break;
      
      case WIFI_CONFIG_SCAN_DONE:          
          break;
      case WIFI_CONFIG_TRY_CONNECT:
          Serial.println("Try connet");
          // ret = WiFi.begin(auth->ssid,auth->password);
          ret = WiFi.begin(WIFI_SSID,WIFI_PASSWORD);
          //创建定时器,once
          timerhandle_wifi = xTimerCreate(
                  "wifi timer",
                  pdMS_TO_TICKS(1000*20),
                  pdFALSE,
                  0,
                  vTimerCallback);
          xTimerStart(timerhandle_wifi,0);
          break;
      case WIFI_CONFIG_CONNECT_FAIL:
          Serial.println("Connect Fail,Power OFF WiFi");
          WiFi.disconnect(true);
          xTimerDelete(timerhandle_wifi,0);//删除定时器
          Serial.println("timer deleted  ");
          break;
      case WIFI_CONFIG_CONNECT_SUCCESS:
          Serial.println("Connect Success");
          xTimerDelete(timerhandle_wifi,0);//删除定时器
          Serial.println("timer deleted  ");
          
          if(state_time_sync==false)
          {
              event_data.type = MSG_TIME;
              event_data.time.event = TIME_SYNC;
              xQueueSend(g_event_queue_handle, &event_data, portMAX_DELAY);
          }
          

          event_data.type = MSG_WEATHER;
          event_data.wewather.event = WEATHER_SYNC_START;
          xQueueSend(g_event_queue_handle, &event_data, portMAX_DELAY);
          break;
      default:break;
    }


}


//weather handle
#include "ArduinoJson.h"
#include "app/weather.h"
void weather_handle(void *data)
{
  task_event_data_t event_data;
  weather_struct_t *p = (weather_struct_t *)data;
  switch(p->event)
  {

    case WEATHER_SYNC_START:
        Serial.println("----------------");
        Serial.printf("free heap:%d\n" ,esp_get_free_heap_size() );
        // Serial.println("weather sync start");
        // xEventGroupSetBits(g_sync_event_group, BIT0);
        Serial.println("set EventGroupHandle_t");
        weather_sync(NULL);
        event_data.type = MSG_WEATHER;
        event_data.wewather.event = WEATHER_SYNC_DONE;
        xQueueSend(g_event_queue_handle, &event_data, portMAX_DELAY);
        break;
    
    case WEATHER_SYNC_DONE:
        // Serial.println("weather sync done");
        
        WiFi.disconnect(true);
        // Serial.println("OFF wifi");
        // weather_draw();
        Serial.printf("free heap:%d\n" ,esp_get_free_heap_size() );
        Serial.println("----------------");
        break;


    default:break;
  }


}











static void lvgl_loop(void *para)
{
  while(1)
  {
    
  }
} 